<template>
  <!-- 访问权新增、修改 -->
    <Modal v-model="accessVisible" :title="isEdit ? '修改访问权' : '新增访问权' " @on-cancel="accessSetManiCancel" width="700">
      <div class="modal-add">
        <Form ref="accessForm" :model="accessForm" :rules="accessSetRules" :label-width="90" label-position="left">
          <FormItem label="名称" prop="id">
            <Input v-model.trim="accessForm.id" placeholder="请输入名称" :disabled="isEdit"></Input>
          </FormItem>
          <FormItem label="域名" prop="level3domen">
            <Input v-model.trim="accessForm.level3domen" placeholder="请输入环境域名">
              <span slot="append">{{accessForm.host | domainPostFix}}</span>
            </Input>
          </FormItem>
          <FormItem label="请求体限制(M)" prop="maxBodySize">
            <Input v-model.trim="accessForm.maxBodySize" placeholder="范围：1-1000"></Input>
          </FormItem>
          <FormItem label="路径列表">
            <Row :gutter="10" class="fold-list-title" v-if="pathList.length > 0">
              <Col :span="8">路径</Col>
              <Col :span="8">服务名称</Col>
              <Col :span="5">服务端口</Col>
            </Row>
            <Row :gutter="10" v-for="path in pathList" :key="path.id" class="fold-list-item">
              <Col :span="8">
                <Input v-model.trim="path.path" placeholder="/"></Input>
              </Col>
              <Col :span="8">
                <Input v-model="path.serviceId" disabled v-if="isService"></Input>
                <Select v-model="path.serviceId" v-else>
                  <Option :value="service.name" :key="service.id" v-for="service in serviceList">{{service.name}}</Option>
                </Select>
              </Col>
              <Col :span="5" :class="{'error-item': path.error}">
                <Input v-model.trim="path.servicePort" placeholder="8080" @on-change="validPort($event, path)" ></Input>
                <div class="ivu-form-item-error-tip ivu-form-item-error-tip-item">范围：1-65536</div>
              </Col>
              <Col :span="3">
                <Icon type="ios-remove-circle-outline" class="remove-icon" v-if="pathList.length > 1" @click="minusItem(path)" />
              </Col>
            </Row>
            <Button type="primary" @click="addItem"><Icon type="md-add"></Icon> 添加</Button>
          </FormItem>
        </Form>
      </div>
      <div slot="footer">
        <Button type="warning" @click="accessSetManiCancel">取消</Button>
        <Button type="primary" :loading="isAdding" @click="accessSetManiConf">确定</Button>
      </div>
    </Modal>
</template>
<script type="text/javascript">
import uuid from 'uuid/v4'
import Fetch from '@/api/request'
export default {
  data() {
    const validateName = (rule, value, callback) => {
      let regName = /^(?!-)(?!.*?-$)[a-z0-9-]{1,}$/
      if (!value) {
        callback(new Error('请输入名称'))
      } else if (!regName.test(value)) {
        callback(new Error('由小写字母、数字、-组成，以小写字母、数字开头和结尾'))
      } else if (value.length < 4) {
        callback(new Error('最小长度不能少于4位'))
      } else if (value.length > 32) {
        callback(new Error('最大长度不能大于32位'))
      } else {
        callback()
      }
    }
    const validateDomain = (rule, value, callback) => {
      let regName = /^(?!-)(?!.*?-$)[a-z0-9-.]{1,}$/
      if (!value) {
        callback(new Error('请输入域名'))
      } else if (!regName.test(value)) {
        callback(new Error('由小写字母、数字、-、.组成，以小写字母、数字开头和结尾'))
      } else if (value.length > 128) {
        callback(new Error('最大长度不能大于128位'))
      } else {
        callback()
      }
    }

    const validateSize = (rule, value, callback) => {
      if ((parseInt(value) <= 1000 && parseInt(value) > 0) || !value) {
        callback()
      } else {
        callback(new Error('请输入1-1000中的数字'))
      }
    }

    return {
      accessForm: {
        environmentName: '',
        id: '',
        host: '',
        maxBodySize: '8',
        level3domen: '',
        paths: []
      },
      isAdding: false,
      accessSetRules: {
        id: [{required: true, trigger: 'blur', validator: validateName}],
        level3domen: [{required: true, trigger: 'blur', validator: validateDomain}],
        maxBodySize: [{required: false, trigger: 'blur', validator: validateSize}]
      },
      accessVisible: false,
      pathList: [{
        id: uuid(),
        path: '/',
        serviceId: '',
        servicePort: '80',
        error: false
      }],
      serviceList: [],
      isEdit: false,
      isService: false
    }
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    form: {
      type: Object,
      default: function () {
        return {}
      }
    }
  },
  mounted() {
    this.getServiceList()
  },
  filters: {
    domainPostFix(val) {
      if (val) {
        let dArr = val.split('.')
        if (dArr.length > 3) {
          return `.${dArr[dArr.length - 3]}.${dArr[dArr.length - 2]}.${dArr[dArr.length - 1]}`
        } else if (dArr.length === 3) {
          return `.${dArr[dArr.length - 2]}.${dArr[dArr.length - 1]}`
        }
      }
      return ''
    }
  },
  methods: {
    // 校验端口
    validPort(event, path) {
      // 校验是符合要求的数字
      let reg = /^\d+$/gi
      let index = 0
      for (let i = 0; i < this.pathList.length; i++) {
        const p = this.pathList[i]
        if (p.id === path.id) {
          index = i
          break
        }
      }
      if (reg.test(path.servicePort) && parseInt(path.servicePort) < 65535) {
        this.$set(this.pathList, index, Object.assign({}, path, {error: false}))
      } else {
        this.$set(this.pathList, index, Object.assign({}, path, {error: true}))
      }
    },
    // 获取服务列表
    getServiceList() {
      Fetch.get({
        url: '/api/environments/' + this.$route.params.environmentId + '/serviceList'
      }).then((res) => {
        if (res && res.code === '0') {
          this.serviceList = res.data
        } else {
          this.$Message.warning({
            content: res.message || '服务器内部错误',
            duration: this.DURATION
          })
        }
      }).catch((err) => {
        this.$Message.error(err.message)
      })
    },
    // 删除路径项
    minusItem(path) {
      this.pathList = this.pathList.filter((item) => {
        return item.id !== path.id
      })
    },
    // 添加服务项
    addItem() {
      // 用于限制无限制添加
      if (this.pathList.length > 20) {
        this.$Message.info({
          content: '路径列表数量不能超过20个',
          duration: this.DURATION
        })
        return
      }
      let serviceId = ''
      if (this.isService) {
        serviceId = this.pathList[this.pathList.length - 1].serviceId
      }
      this.pathList.push({
        id: uuid(),
        path: '/',
        serviceId: serviceId,
        servicePort: '80',
        error: false
      })
    },
    // 确认访问权操作
    accessSetManiConf() {
      this.$refs['accessForm'].validate((valid) => {
        if (valid) {
          // 路径校验
          for (let i = 0; i < this.pathList.length; i++) {
            const path = this.pathList[i]
            if (!path.path) {
              this.$Message.warning({
                content: '有路径未填写，请先填写完整！',
                duration: this.DURATION
              })
              return
            } else if (path.path.length > 1024) {
              this.$Message.warning({
                content: '有填写路径太长，请修改！',
                duration: this.DURATION
              })
              return
            }
            if (!path.serviceId) {
              this.$Message.warning({
                content: '有路径服务名称未填写，请先选择！',
                duration: this.DURATION
              })
              return
            }
            if (!(/^\d+$/gi.test(path.servicePort) && parseInt(path.servicePort) < 65535 && parseInt(path.servicePort) > 0)) {
              this.$Message.warning({
                content: '填写端口不符合规范，端口范围为：（0 - 65535）',
                duration: this.DURATION
              })
              return
            }
          }

          this.accessForm.environmentName = this.$route.params.environmentId
          this.accessForm.paths = this.pathList
          this.isAdding = true
          if (this.isEdit) {
            Fetch.put({
              url: '/api/environments/' + this.$route.params.environmentId + '/ingresses/' + this.accessForm.id,
              params: this.accessForm
            }).then((res) => {
              if (res && res.code === '0') {
                this.$Message.success({
                  content: '访问权修改成功！',
                  duration: this.DURATION
                })
                this.$emit('update:visible', false)
                this.$emit('finish', this.accessForm)
              } else {
                this.$Message.warning({
                  content: res.message || '服务器内部错误',
                  duration: this.DURATION
                })
              }
              this.isAdding = false
            }).catch((err) => {
              this.isAdding = false
              this.$Message.error(err.message)
            })
          } else {
            Fetch.post({
              url: '/api/environments/' + this.$route.params.environmentId + '/ingresses',
              params: this.accessForm
            }).then((res) => {
              if (res && res.code === '0') {
                this.$Message.success({
                  content: '访问权新增成功！',
                  duration: this.DURATION
                })
                this.$emit('update:visible', false)
                this.$emit('finish', this.accessForm)
              } else {
                this.$Message.warning({
                  content: res.message || '服务器内部错误',
                  duration: this.DURATION
                })
              }
              this.isAdding = false
            }).catch((err) => {
              this.isAdding = false
              this.$Message.error(err.message)
            })
          }
        }
      })
    },
    // 取消配置集操作
    accessSetManiCancel() {
      this.$emit('update:visible', false)
    }
  },
  watch: {
    visible(val) {
      let vm = this
      vm.accessVisible = val
      if (val) {
        vm.isEdit = !!vm.form.environmentId
        vm.accessForm = Object.assign({}, vm.form)
        vm.$refs.accessForm.resetFields()
        // 直接通过服务添加访问权标志
        vm.isService = !!vm.form.isService
        if (vm.form.paths && vm.form.paths.length > 0) {
          let t = []
          for (let i = 0; i < vm.form.paths.length; i++) {
            const path = vm.form.paths[i]
            path.id = uuid()
            t.push(path)
          }
          vm.pathList = t
        } else {
          vm.pathList = []
        }
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.error-item {
  .ivu-form-item-error-tip-item {
    padding-top: 2px;
  }
}
</style>
